package com.gaolang.web.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.gaolang.web.config.security.JwtTokenUtil;
import com.gaolang.web.entities.Department;
import com.gaolang.web.entities.User;
import com.gaolang.web.enums.UserStatusEnum;
import com.gaolang.web.enums.UserTypeEnum;
import com.gaolang.web.handler.BusinessException;
import com.gaolang.web.mapper.DepartmentMapper;
import com.gaolang.web.mapper.UserMapper;
import com.gaolang.web.response.Result;
import com.gaolang.web.response.ResultCode;
import com.gaolang.web.service.IUserService;
import com.gaolang.web.vo.UserLogin;
import com.gaolang.web.vo.UserVO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletRequest;
import java.util.*;

/**
 * <p>
 * 用户表 服务实现类
 * </p>
 *
 * @author gaolang
 * @since 2021-02-22
 */
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements IUserService {

    @Autowired
    private UserMapper userMapper;

    @Autowired
    private DepartmentMapper departmentMapper;

    @Autowired
    private PasswordEncoder passwordEncoder;

    @Autowired
    private UserDetailsService userDetailsService;

    @Autowired
    private JwtTokenUtil jwtTokenUtil;

    @Value("${jwt.tokenHead}")
    private String tokenHead;

    @Override
    public List<User> selectAllUsers() {
        return userMapper.selectList(null);
    }

    @Override
    public User findUserById(Long id) {
        return userMapper.selectById(id);
    }

    @Override
    public Page<User> findUserByPage(Integer current, Integer size) {
        Page<User> page = new Page<>(current,size);

        return userMapper.selectPage(page, null);
    }

    @Override
    public IPage<User> findUserPage(IPage<User> page,UserVO userVO) {
        return userMapper.findUserPage(page,userVO);
    }

    @Override
    public int addUser(User user) {
        //判断是否用户名重复
        String username = user.getUsername();
        QueryWrapper<User> wrapper = new QueryWrapper<>();
        wrapper
                .eq("username",username);
        Integer count = userMapper.selectCount(wrapper);
        if (count != 0) {
            //抛出账号已存在
            throw new BusinessException(ResultCode.USER_ACCOUNT_ALREADY_EXIST.getCode(),ResultCode.USER_ACCOUNT_ALREADY_EXIST.getMessage());

        }

        //判断部门
        Long departmentId = user.getDepartmentId();
        Department department = departmentMapper.selectById(departmentId);
        if (Objects.isNull(department)){
            throw new BusinessException(ResultCode.DEPARTMENT_NOT_EXIST.getCode(),ResultCode.DEPARTMENT_NOT_EXIST.getMessage());
        }

        //盐：之前是Shiro，现在是Security，暂时随机生成保存到数据库，没有意义
        String salt = UUID.randomUUID().toString().substring(0, 32);
        user.setSalt(salt);
        //使用SpringSecurity自带的密码加密策略
        user.setPassword(passwordEncoder.encode(user.getPassword()));
        //用户类型：普通用户
        user.setType(UserTypeEnum.SYSTEM_USER.getTypeCode());
        //用户状态
        user.setStatus(UserStatusEnum.AVAILABLE.getStatusCode());
        //删除状态
        user.setDeleted(false);
        return userMapper.insert(user);
    }

    @Override
    public Result login(UserLogin userLogin, HttpServletRequest httpServletRequest) {
        UserDetails userDetails = userDetailsService.loadUserByUsername(userLogin.getUsername());
        //账号不存在
        if (null == userDetails) {
            throw new BusinessException(ResultCode.USER_ACCOUNT_NOT_EXIST.getCode(),ResultCode.USER_ACCOUNT_NOT_EXIST.getMessage());
        }
        //密码不正确
        if (!passwordEncoder.matches(userLogin.getPassword(),userDetails.getPassword())) {
            throw new BusinessException(ResultCode.USER_CREDENTIALS_ERROR.getCode(),ResultCode.USER_CREDENTIALS_ERROR.getMessage());
        }
        //禁用
        if (userDetails.isEnabled()) {
            throw new BusinessException(ResultCode.USER_ACCOUNT_DISABLE.getCode(),ResultCode.USER_ACCOUNT_DISABLE.getMessage());
        }

        //更新security登录用户对象
        UsernamePasswordAuthenticationToken authenticationToken = new
                UsernamePasswordAuthenticationToken(userDetails,null,userDetails.getAuthorities());
        //然后放到spring security的全局里面
        SecurityContextHolder.getContext().setAuthentication(authenticationToken);

    //拿到token
        String token = jwtTokenUtil.generateToken(userDetails);
        Map<String,String> tokenMap = new HashMap<>();
        tokenMap.put("token",token);
        //头部信息
        tokenMap.put("tokenHead",tokenHead);

        return Result.ok().data("token",tokenMap);
    }

    @Override
    public User getUserByUsername(String username) {
        return userMapper.selectOne(new QueryWrapper<User>()
                .eq("username",username)
                .eq("deleted",0));
    }

}
